# -*- coding: utf-8 -*-

# 生命灵动，当用激情跃起奋发之力






import pygame,sys,time




pygame.init() # 初始化pygame

# 初始设置
screen = pygame.display.set_mode((600,800)) # Pygame窗口
pygame.display.set_caption("离线CPS测试工具") # 标题




BLUE = (0,137,242)
BLUE_PRESSED = (38, 226, 255)
RED = (255,52,50)
PURPLE = (171,112,255)
GREEN = (0,255,33)
WHITE = (242,244,246)
BLACK = (18,17,16)









def drawSquare(surface: pygame.Surface, color:tuple, position:tuple, size:tuple) -> None:
    '''在`surface`上绘制矩形

    Parameter
    ---------
    surface: :class:`pygame.Surface`
        pygame Surface对象
    color: :class:`tuple`
        颜色数组(RGB)或(RGBA)
    position: :class:`tuple`
        矩形左上角的位置
    size: :class:`tuple`
        矩形大小(以像素为准)
    '''
    pygame.draw.rect(
        surface,
        color,
        pygame.rect.Rect(
            int(position[0]),
            int(position[1]),
            int(size[0]),
            int(size[1])
        )
    )





def drawHollowSquare(surface: pygame.Surface, color:tuple, position:tuple, size:tuple, width:int = 1) -> None:
    '''在`surface`上绘制空心矩形

    Parameter
    ---------
    surface: `pygame.Surface`
        pygame Surface对象
    color: `tuple`
        颜色数组(RGB)或(RGBA)
    position: `tuple`
        矩形左上角的位置
    size: `tuple`
        矩形大小(以像素为准)
    width: `int`
        矩形边宽度(以像素为准)
    '''

    pygame.draw.rect(
        surface,
        color,
        pygame.Rect(int(position[0]), int(position[1]), size[0], size[1]),
        width
    )





def drawText(surface: pygame.Surface, text: str, color: tuple, position: tuple, size: int, isBold=False, isItalic=False, font='DengXian', isAntialias=True, bg=None) -> None:
    '''在`surface`上写下`text`

    Parameter
    --------
    surface: `pygame.Surface`
        pygame Surface对象
    text: `str`
        显示的文字
    color: `tuple`
        颜色数组(RGB)或(RGBA)
    position: `tuple`
        文字左上角的位置
    size: int
        文字字号(以像素为准)
    isBold: `bool`
        是否加粗 默认为 `False`
    isItalic: `bool`
        是否斜体 默认为 `False`
    font: `str`
        字体 默认为 `DengXian`
    isAntialias: `bool`
        是否使用平滑字体 默认为 `True`
    bg: `tuple`
        背景颜色 默认为 `None`，即无背景色
    '''
    surface.blit(
        pygame.font.SysFont(
            font,
            int(size),
            isBold,
            isItalic
        ).render(
            text,
            isAntialias,
            color,
            bg
        ),
        (
            int(position[0]),
            int(position[1]),
        )
    )





def drawNoticeTitle(surface: pygame.Surface,text:str,color = WHITE) -> None:
    '''在`surface`上把`text`绘制棋盘上面作为提示标题

    Parameters
    ---------
    surface: `pygame.Surface`
        pygame Surface对象
    text: `str`
        需要显示的标题
    color: `tuple`
        标题颜色
    '''
    drawText(
        surface,
        text,
        color,
            (
                10,
                0
            ),
        int(surface.get_height()/16)
    )






def drawLineChart(surface:pygame.Surface,datas:list,LAunit:str='次',HAunit:str = '秒',position:tuple = (50,500),size:tuple = (500,250),color:tuple = WHITE,textColor:tuple = BLUE):
    '''在`surface`上的`position`位置，以`datas`作为数据，绘制，大小为`size`，颜色为`color`的折线统计图

    Parameters
    ---------
    surface: `pygame.Surface`
        pygame Surface对象
    datas: `list[int|float..]`
        用于绘制表格的数据
    LAunit: `str`
        绘制在纵轴上的数据单位
    HAunit: `str`
        绘制在横轴上的数据单位
    position: `tuple`
        绘制表格的左上角的位置
    size: `tuple`
        绘制表格的最大大小
    color: `tuple`
        折线颜色
    textColor: `tuple`
        绘制文字的颜色
    '''

    if len(datas) < 2:
        return

    # 纵轴线
    pygame.draw.aaline(surface, color, (position[0]+size[0]/50,position[1]), (position[0]+size[0]/50,position[1]+size[1]), blend=1)

    # 横轴线
    pygame.draw.aaline(surface, color, (position[0],position[1]+size[1]-size[1]/25), (position[0]+size[0],position[1]+size[1]-size[1]/25), blend=1)

    pointlist = []
    x_increment = size[0]*49/50 / len(datas)
    x = position[0]+size[0]/50
    ymax = max(datas)
    # 横排数据y值
    y_HA = position[1]+size[1]-size[1]/25
    for i in datas:
        # 画线点阵
        pointlist.append(
            (
                int(x+0.5),
                int(position[1] + size[1] * 24 / 25 - (size[1] * 24 / 25) / ymax * i + 0.5) if ymax != 0 else 0
            )
        )
        # 横排数据
        drawText(
            surface,
            str(int(x/x_increment)),
            textColor,
            (
                int(x+0.5),
                y_HA
            ),
            size[1]/25
        )
        # 纵列数据
        drawText(
            surface,
            str(i),
            textColor,
            (
                int(x),
                int(position[1] + size[1] * 11.5 / 12.5 - (size[1] * 24 / 25) / ymax * i + 0.5 ) if ymax != 0 else 0
            ),
            size[1]/25,
            True
        )
        x += x_increment

    # 绘制单位

    # 横轴末尾
    drawText(surface,HAunit,textColor,(position[0]+size[0],y_HA),size[1]/20,True,True)
    # 纵轴末尾
    drawText(surface,LAunit,textColor,(position[0]-0.5-len(LAunit)*size[1]/20,position[1]-0.5),size[1]/20,True,True)


    # 图表
    pygame.draw.aalines(surface, color, False, pointlist)
    






def runtime(testTime:int = 10):
    pos = (0,0)
    '''指针坐标'''

    isStarted = False
    isPressed = False
    countTimes = 0
    lastTimes = 0
    T = 0
    last10 = int(time.time()*10)


    listData = []





    # def __display():





    # 总控循环
    while (time.time() <= T) if isStarted else True:
        events = pygame.event.get()
        if events:
            for event in events: #遍历事件
                if event.type == pygame.QUIT:  # 退出事件
                    # print("EXIT")
                    pygame.quit()
                    sys.exit()
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    # 按下鼠标？
                    if event.button == 1:
                        # 按下左键？
                        pos = event.pos
                        if pos[0] in tuple(range(100,500)) and pos[1] in tuple(range(200,450)):
                            #在按键范围内
                            
                            if not isStarted:
                                isStarted = True
                                T = time.time() + testTime
                            isPressed = True
                elif event.type == pygame.MOUSEBUTTONUP:
                    # 抬起鼠标？
                    if event.button == 1:
                        # 抬起左键？
                        pos = event.pos
                        if pos[0] in tuple(range(100,500)) and pos[1] in tuple(range(200,450)):
                            #在按键范围内
                            if isStarted and isPressed:
                                isPressed = False
                                countTimes += 1
        
        
        # threading.Thread(None,__display,tuple()).start()

        screen.fill(BLACK)
        drawSquare(screen,BLUE_PRESSED if isPressed else BLUE,(100,200),(400,250))
        
        now = time.time()
        
        drawNoticeTitle(screen,str(countTimes / (now + 11 - T))+' CPS' if isStarted else '就绪')
        

        if isStarted:
            if int(now*10)!=last10:
                # 每 0.1 秒的数据
                listData.append(countTimes - lastTimes)
                lastTimes = countTimes
                last10 = int(now*10)

            drawLineChart(screen,listData)
        
        pygame.display.update()  # 刷新屏幕


        

    
    return countTimes,listData






def __main__():
    result,datas=runtime()
    while True:
        events = pygame.event.get()
        if events:
            for event in events: #遍历事件
                if event.type == pygame.QUIT:  # 退出事件
                    # print("EXIT")
                    pygame.quit()
                    sys.exit()
        screen.fill(BLACK)
        drawNoticeTitle(screen,f'您的测试结果：{result/10} CPS')
        drawLineChart(screen,datas)
        pygame.display.update() 





if __name__ == '__main__':
    __main__()